//
//  HTPullDownRefreshControl.swift
//  mySinaBlog
//
//  Created by whtapple on 3/29/16.
//  Copyright © 2016 whtapple. All rights reserved.
//

import UIKit
private var pullDownRefreshConteolKey = "pullDownRefreshConteolKey"
//MARK: -扩展 Scrollview,动态添加下拉刷新控件属性方便使用下拉刷新
extension UIScrollView{
    //添加计算性属性
    private var pullDownRefreshControl: HTPullDownRefreshControl{
        get{
            if let refreshControl = objc_getAssociatedObject(self, &pullDownRefreshConteolKey) as? HTPullDownRefreshControl{
                return refreshControl
            }else{
                let refreshControl = HTPullDownRefreshControl()
                self.addSubview(refreshControl)
                self.pullDownRefreshControl = refreshControl
                return refreshControl
            }
        }
        set{
            objc_setAssociatedObject(self, &pullDownRefreshConteolKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    //MARK: -添加3个对外公开的方法，不让外部直接访问下拉刷新控件属性
    ///添加开始刷新的闭包
    func addpulldownRefreshHader(handler: () -> ()){
        pullDownRefreshControl.pulldownHandler = handler
    }
    ///添加开始刷新
    func startRefreshing() {
        pullDownRefreshControl.startRefresh()
    }
    /// 结束刷新
    func endRefreshing() {
        pullDownRefreshControl.endRefresh()
    }
}
//MARK: -刷新的几种状态枚举
enum PulldownRefreshControlStatus: Int {
    case Nomal             //箭头朝上
    case PullToRefresh     //箭头朝下
    case Refreshing          // 刷新状态
}
class HTPullDownRefreshControl: UIView {
    //MARK: -属性
    //父控件属性，因为用到时，父控件会引用子控件所以在这里是若引用，叹号是隐式拆包，如果没有值还是会挂掉
    private weak var scrollerView: UIScrollView!
    //外面回调的闭包
    var pulldownHandler:(() -> ())?
    //上一状态
    private var lastStatus: PulldownRefreshControlStatus = .Nomal
    // 当前状态
    private var currentStatus: PulldownRefreshControlStatus = .Nomal{
        didSet{
            //根据当前状态，设置控件状态和调用方法
            switch currentStatus{
            case .Nomal:
                arrowView.hidden = false
                fhlView.hidden = true
                massageLabel.text = "下拉刷新"
                arrowView.transform = CGAffineTransformIdentity
                //从正在刷新回来时，让contentInset还原
                if lastStatus == .Refreshing{
                    self.scrollerView.contentInset.top -= defaultHeight
                }
            case .PullToRefresh:
                massageLabel.text = "释放刷新"
                arrowView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
            case .Refreshing:
                arrowView.hidden = true
                fhlView.hidden = false
                massageLabel.text = "正在刷新"
                //核心动画，让它转起来
                let rotation = CABasicAnimation(keyPath: "transform.rotation")
                rotation.duration = 0.5
                rotation.toValue = M_PI * 2
                rotation.repeatCount = MAXFLOAT
                fhlView.layer.addAnimation(rotation, forKey: "rotation")
                //动画到刷新状态
                UIView.animateWithDuration(defaultduration * 2, animations: { () -> Void in
                    self.scrollerView.contentInset.top += self.defaultHeight
                    }, completion: { (_) -> Void in
                        //执行闭包回调
                        self.pulldownHandler?()
                })
            }
            lastStatus = currentStatus
        }
    }
    //下拉刷新页面高度
    let defaultHeight: CGFloat = 60
    //tabelView的原始 offset
    let defaultOffset: CGFloat = -64
    //初始化，指定尺寸
    override init(frame: CGRect) {
        let newframe = CGRectMake(0, -defaultHeight, UIScreen.width, defaultHeight)
        super.init(frame: newframe)
        prepareUI()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //MARK: -准备 UI
    private func prepareUI(){
//        backgroundColor = UIColor.purpleColor()
        //添加子控件
        addSubview(arrowView)
        addSubview(fhlView)
        addSubview(massageLabel)
        //先让风火轮隐藏
        fhlView.hidden = true
        //约束
        arrowView.translatesAutoresizingMaskIntoConstraints = false
        fhlView.translatesAutoresizingMaskIntoConstraints = false
        massageLabel.translatesAutoresizingMaskIntoConstraints = false
        //arrowView进行约束
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0))
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: -30))
        //fhlView进行约束
        addConstraint(NSLayoutConstraint(item: fhlView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0))
        addConstraint(NSLayoutConstraint(item: fhlView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0))
        //massageLabel进行约束
        addConstraint(NSLayoutConstraint(item: massageLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0))
        addConstraint(NSLayoutConstraint(item: massageLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 10))
    }
    //Mark: -添加监听
    override func willMoveToSuperview(newSuperview: UIView?) {
        super.willMoveToSuperview(newSuperview)
        //当父控件存在时，监听父控件的contentoffset 属性
        if let scrollerView = newSuperview as? UIScrollView{
            self.scrollerView = scrollerView
            scrollerView.addObserver(self, forKeyPath: "contentOffset", options: [NSKeyValueObservingOptions.Old,NSKeyValueObservingOptions.New], context: nil)
        }
    }
    ///监听 KVO 回调
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        // print("监听了回调")
        if scrollerView.dragging{
            if currentStatus == .PullToRefresh && scrollerView.contentOffset.y > defaultOffset - defaultHeight{
                Xprint(msg: "转到下拉刷新")
                currentStatus = .Nomal
            }else if(currentStatus == .Nomal && scrollerView.contentOffset.y < (defaultOffset - defaultHeight)){
                Xprint(msg: "转到释放刷新")
                currentStatus = .PullToRefresh
            }
        }else if currentStatus == .PullToRefresh {
            Xprint(msg: "转到正在刷新状态")
            currentStatus = .Refreshing
        }
    }
    ///移除监听
    deinit{
        scrollerView.removeObserver(self, forKeyPath: "contentOffset")
    }
    //MARK: -刷新结束和开始刷新
    private func endRefresh(){
        currentStatus = .Nomal
    }
    private func startRefresh(){
        currentStatus = .Refreshing
    }
    //懒加载数据
    private lazy var arrowView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //懒加载数据
    private lazy var fhlView: UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    //懒加载数据
    private lazy var massageLabel: UILabel = {
        let tempLabel = UILabel()
        tempLabel.text = "下拉刷新"
        tempLabel.font = UIFont.systemFontOfSize(bigfontsize)
        tempLabel.textColor = UIColor.darkGrayColor()
        return tempLabel
    }()
}
